
//FYI: https://github.com/Tencent/puerts/blob/master/doc/unity/manual.md

import FairyEditor = CS.FairyEditor;
import { XMLParser } from "./xmlUIParse/XMLParser";
import { IXMLData } from "./xmlUIParse/IXMLData";
import { Setting } from "./Setting";
import { Util } from "./Util";
import { XMLConfig } from "./xmlUIParse/XMLConfig";
import { IXMLTag } from "./xmlUIParse/IXMLTag";
import { IXMLAttr } from "./xmlUIParse/IXMLAttr";
const App = FairyEditor.App;
const fs = CS.System.IO.File;
const director = CS.System.IO.Directory;
const Path = CS.System.IO.Path;
console.log('欢迎使用羔羊引擎之fairgui插件');

const setting:Setting = new Setting;
// let onTestPlay = new CS.FairyGUI.EventCallback1((c) => {
//     console.log("test is play");
// });
// App.On(FairyEditor.EditorEvents.TestStart, onTestPlay);
function getAllXML(path:string, result:string[]=null):string[]
{
    if(result == null)
        result = [];
    if(director.Exists(path))//文件夹
    {
        let arr = director.GetFiles(path);
        let i:number,len:number;        
        len = arr.Length;
        for(i=0;i<len;++i)
        {
            path = arr.get_Item(i);
            if(director.Exists(path))
                getAllXML(path, result);
            else if(path.indexOf(".xml") == path.length - 4)
                result.push(path);
        }
    }
    else if(path.indexOf(".xml") == path.length - 4)
        result.push(path);
    return result;
}
function findPkg(pkg:string):FairyEditor.FPackage
{
    let len:number;
    let allPage = App.project.allPackages;
    len = allPage.Count;
    while(--len>-1)
    {
        let item:FairyEditor.FPackage = allPage.get_Item(len);           
        if(item.id == pkg)
            return item;        
    }
    return null;
}
/**打包所有包*/
function packAll():void
{
    let allPage = App.project.allPackages;
    let i:number,len:number;    
    let layoutTS:string;
    Util.packInit();
    layoutTS = setting.getLayoutTS();
    len = allPage.Count;
    for(i=0;i<len;++i)
    {
        let item:FairyEditor.FPackage = allPage.get_Item(i);   
        pack(item, layoutTS);
    }   
}
/**打包单个包*/
function pack(pkg:FairyEditor.FPackage, layoutTS:string=null):void
{    
    let i:number,len:number,j:number,len2:number,len3:number;
    let files:string[],nameArr:string[];
    let content:string,fileName:string, packageName:string, displayName:string, pkgName:string, referencePkg:string;
    let packDecsName:string;
    let xmlData:IXMLData,packageData:IXMLData,displayData:IXMLData;
    let displayList:IXMLData[];
    let parser:XMLParser;
    let tsStr:string;
    
    
    nameArr = pkg.basePath.split("\\");
    packageName = nameArr[nameArr.length - 1];
    
    if(Util.packageDict[packageName])
        return;
    
    console.log("正在发布包...." + pkg.basePath);
    packDecsName = "package.xml";
    pkgName = packageName.split(".")[0];
    parser = XMLParser.getInstance();
    
    files = getAllXML(pkg.basePath);
    files.sort((a:string, b:string):number=>{
        if(a.indexOf("\\" + packDecsName) > -1)
            return -1;
        return 1;
    });        
    len = files.length;
    if(len > 0)
    {
        let pkgId:string = null;
        let dict:{[key:string]:IXMLData} = {};        
        for(i=0;i<len;++i)
        {
            content = fs.ReadAllText(files[i]);
            nameArr = files[i].split("\\");
            fileName = nameArr[nameArr.length - 1];
            xmlData = dict[fileName] = parser.parse(content, pkgId);
            xmlData.fileName = fileName; 
            if(packageData && layoutTS)
            {
                //引用其他包
                let result:IXMLData[] = parser.getTags(xmlData, ["displayList"]);
                if(result[0])
                {
                    let childs:IXMLData[] = result[0].childs;
                    len2 = childs.length;
                    while(--len2>-1)
                    {
                        referencePkg = childs[len2].attrs.pkg;
                        if(referencePkg && Util.referencePkgs.indexOf(referencePkg) == -1)
                            Util.referencePkgs.push(referencePkg);                        
                    }                                        
                }                        
                Util.packageDict[pkgId].components.push(xmlData);                    
            }
            if(i == 0)
            {//描述文件
                pkgId = xmlData.attrs.id;
                packageData = xmlData;
                //由于package.xml的九宫格描述是[x,y,w,h]，需要转换成[left,top,right,bottom]，遍历处理一下
                len2 = xmlData.childs[0].childs.length;
                for(j=0;j<len2;++j)
                {
                    let descObj:any = xmlData.childs[0].childs[j];
                    let item: FairyEditor.FPackageItem = pkg.GetItem(descObj.attrs.id);
                    let scale9gridArr:number[];
                    if(descObj.attrs.scale9grid)
                    {
                        scale9gridArr = descObj.attrs.scale9grid;
                        scale9gridArr[0] = Number(scale9gridArr[0]);
                        scale9gridArr[1] = Number(scale9gridArr[1]);
                        scale9gridArr[2] = item.width - scale9gridArr[0] - scale9gridArr[2];
                        scale9gridArr[3] = item.height - scale9gridArr[1] - scale9gridArr[3];
                        descObj.scale9grid = scale9gridArr.join(",");                                                
                    }               
                    if(Number(descObj.attrs.scaleX) != Number(descObj.attrs.scaleX))
                        delete descObj.attrs.scaleX;
                    if(Number(descObj.attrs.scaleY) != Number(descObj.attrs.scaleY))
                        delete descObj.attrs.scaleY;                        
                }
                
                Util.packageDict[pkgId] = {packageData:xmlData, components:[],pkgId:pkgId,pkgName:packageName};
            }
        }        
        
        //输出配置
        let resultPath:string;
        resultPath = Path.GetFullPath(packageName + ".json", setting.uiJsonPath);            
        fs.WriteAllText(resultPath, JSON.stringify(dict,null,4));
        console.log("发布配置完成:"+resultPath, Util.referencePkgs.length);
        
        if(Util.referencePkgs.length > 0)
        {//处理引用的包
            pkg = findPkg(Util.referencePkgs.pop());
            pack(pkg, layoutTS);
        }
        else
        {//全部关联包都打包完毕，开始导出代码
            let layoutPath:string;            
            let extentionXMLData:IXMLData;
            let cls:string;
            //查询所有需要导出代码的节点数据
            for(pkgId in Util.packageDict)
            {
                let obj:any = Util.packageDict[pkgId];
                let xmlDatas:IXMLData[] = obj.components;                
                len = xmlDatas.length;
                for(i=0;i<len;++i)
                {
                    if(Util.isExported(xmlDatas[i], obj.packageData))
                        Util.exportedList.push(xmlDatas[i], obj); 
                }
                layoutPath = Path.GetFullPath(obj.pkgName, setting.layoutPath);                    
                if(director.Exists(layoutPath))
                    director.Delete(layoutPath, true);
                console.log("开始发布代码...", obj.pkgName);
            }
            
            len = Util.exportedList.length;
            for(i=0;i<len;i+=2)
            {
                xmlData = Util.exportedList[i];
                fileName = xmlData.fileName;
                packageData = Util.exportedList[i+1].packageData;
                pkgName = Util.exportedList[i+1].pkgName;
                tsStr = layoutTS;
                displayList = parser.getTags(xmlData, ["displayList"]);
                //先处理当前文件的关键字替换
                displayName = fileName.split(".")[0];
                tsStr = tsStr.replace(/\{MODULE\}/g, setting.projName + "." + pkgName);
                tsStr = tsStr.replace(/\{PACKAGE\}/g, pkgName);
                tsStr = tsStr.replace(/\{COMPONENT\}/g, displayName);
                if(displayList[0])
                {
                    //再处理文件显示列表的属性替换
                    displayList = displayList[0].childs;                            
                    len2 = displayList.length;
                    for(j=0;j<len2;++j)
                    {
                        displayData = displayList[j];                                                    
                        extentionXMLData = dict[displayData.attrs.fileName];
                        let obj:any = Util.findDescObj(displayData);//存在外部引用，获取外部包名
                        cls = Util.getDefClass(displayData, extentionXMLData, parser, packageData, obj?obj.pkgName:pkgName, setting.defaultCls);                    
                        displayData.cls = cls;
                        tsStr = tsStr.replace(/\{PROPERTY\}/g, `{PROPERTY}\n\t\t${displayData.attrs.name}?:${cls};`);
                    }
                    tsStr = tsStr.replace(/\/\/\{PROPERTY\}/g, "");

                    //输出布局文件                    
                    layoutPath = Path.GetFullPath(pkgName, setting.layoutPath);        
                    if(!director.Exists(layoutPath))
                        director.CreateDirectory(layoutPath);
                    let layoutFilePath:string = Path.GetFullPath(displayName + "Layout.ts", layoutPath);
                    fs.WriteAllText(layoutFilePath, tsStr);
                    console.log(layoutFilePath + "代码生成成功!");
                }            
            }
        }
    }    
}

let menu:FairyEditor.Component.IMenu = App.menu.GetSubMenu("tool");
menu.AddItem("羔羊发布所有包", "GYPublish", (name) => {    
    packAll();
    // let arr:CS.System.Collections.Generic.List$1<FairyEditor.FObject> = <CS.System.Collections.Generic.List$1<FairyEditor.FObject>>App.activeDoc.GetSelection();
    // let len:number = arr.Count;    
    // while(--len>-1)
    // {
    //     let obj:FairyEditor.FObject = arr.get_Item(len);
    //     if(obj.objectType == "inputtext")
    //     {   
    //         let txt:FairyEditor.FTextInput = (<FairyEditor.FTextInput>obj);
    //         console.log(txt.name, txt._rawHeight, txt.height, txt.initHeight, txt._sizePercentInGroup);
    //     }        
    // }
    App.Alert("发布所有包完成!");
    // console.log("发布所有包完成!");
});
menu.AddItem("羔羊发布当前包", "GYPublishCur", (name) => {
    let pkgName:string = App.GetActiveFolder().name; 
    let pck:FairyEditor.FPackage = App.project.GetPackageByName(pkgName);    
    if(pck)
    {
        Util.packInit();        
        pack(pck, setting.getLayoutTS());
        // console.log(pkgName + "-发布完成!");
        App.Alert(pkgName + "-发布完成!");
    }
    else
    {
        // console.error("找不到包:" + pkgName);        
        App.Alert("找不到包:" + pkgName);
    }
        
});

function onDestroy() {
    menu.RemoveItem("GYPublish");
    menu.RemoveItem("GYPublishCur");
    console.warn("onDestroy");
}
function onPublish(){
    console.warn("onPublish");
}
export {onPublish, onDestroy};

global.onPublish = onPublish;
global.onDestroy = onDestroy;